package com.ruoyi.file.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.file.domain.SysStorageConfig;
import com.ruoyi.file.service.ISysStorageConfigService;
import com.ruoyi.file.service.storage.StorageService;
import com.ruoyi.file.service.storage.StorageServiceFactory;
import com.ruoyi.file.utils.ResponseUtils;
import com.ruoyi.file.utils.StorageConfigUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 存储桶管理Controller
 *
 * @author ruoyi
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/file/bucket")
@Tag(name = "存储桶管理", description = "存储桶管理相关接口")
public class BucketController extends BaseController {

    private final ISysStorageConfigService storageConfigService;
    private final StorageServiceFactory storageServiceFactory;

    /**
     * 获取存储桶列表
     */
    @Operation(summary = "获取存储桶列表")
    @SaCheckPermission("file:bucket:list")
    @GetMapping("/list")
    public AjaxResult listBuckets(@RequestParam(value = "configId", required = false) Long configId) {
        try {
            // 获取并验证存储配置
            SysStorageConfig config = StorageConfigUtils.getAndValidateConfig(configId, storageConfigService);
            StorageService storageService = storageServiceFactory.getStorageService(config);
            List<String> bucketNames = storageService.listBuckets(config);
            // 构建完整的桶信息列表
            List<Map<String, Object>> buckets = new ArrayList<>();
            for (String bucketName : bucketNames) {
                Map<String, Object> bucketInfo = new HashMap<>();
                bucketInfo.put("bucketName", bucketName);
                bucketInfo.put("isDefault", bucketName.equals(config.getBucketName()));
                // 获取桶权限
                try {
                    String permission = storageService.getBucketPermission(bucketName, config);
                    bucketInfo.put("permission", permission);
                } catch (Exception e) {
                    log.warn("获取桶 {} 权限失败: {}", bucketName, e.getMessage());
                    bucketInfo.put("permission", "-");
                }
                buckets.add(bucketInfo);
            }
            return AjaxResult.success(buckets);
        } catch (Exception e) {
            return ResponseUtils.handleException(e, "获取存储桶列表");
        }
    }

    /**
     * 创建存储桶
     */
    @Operation(summary = "创建存储桶")
    @SaCheckPermission("file:bucket:add")
    @Log(title = "存储桶管理", businessType = BusinessType.INSERT)
    @PostMapping("/create")
    public AjaxResult createBucket(@RequestParam("bucketName") String bucketName, @RequestParam(value = "configId", required = false) Long configId) {
        try {
            // 获取并验证存储配置
            SysStorageConfig config = StorageConfigUtils.getAndValidateConfig(configId, storageConfigService);
            StorageService storageService = storageServiceFactory.getStorageService(config);
            // 检查桶是否已存在
            if (storageService.bucketExists(bucketName, config)) {
                return AjaxResult.error("存储桶已存在");
            }
            // 创建存储桶
            storageService.createBucket(bucketName, config);
            return AjaxResult.success("创建存储桶成功");
        } catch (Exception e) {
            return ResponseUtils.handleException(e, "创建存储桶");
        }
    }

    /**
     * 删除存储桶
     */
    @Operation(summary = "删除存储桶")
    @SaCheckPermission("file:bucket:remove")
    @Log(title = "存储桶管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/delete")
    public AjaxResult deleteBucket(@RequestParam("bucketName") String bucketName, @RequestParam(value = "configId", required = false) Long configId) {
        try {
            // 获取并验证存储配置
            SysStorageConfig config = StorageConfigUtils.getAndValidateConfig(configId, storageConfigService);

            StorageService storageService = storageServiceFactory.getStorageService(config);

            // 检查桶是否存在
            if (!storageService.bucketExists(bucketName, config)) {
                return AjaxResult.error("存储桶不存在");
            }

            // 删除存储桶
            storageService.deleteBucket(bucketName, config);
            return AjaxResult.success("删除存储桶成功");
        } catch (Exception e) {
            return ResponseUtils.handleException(e, "删除存储桶");
        }
    }

    /**
     * 检查存储桶是否存在
     */
    @Operation(summary = "检查存储桶是否存在")
    @SaCheckPermission("file:bucket:query")
    @GetMapping("/exists")
    public AjaxResult bucketExists(@RequestParam("bucketName") String bucketName, @RequestParam(value = "configId", required = false) Long configId) {
        try {
            // 获取并验证存储配置
            SysStorageConfig config = StorageConfigUtils.getAndValidateConfig(configId, storageConfigService);

            StorageService storageService = storageServiceFactory.getStorageService(config);
            boolean exists = storageService.bucketExists(bucketName, config);
            return AjaxResult.success(exists);
        } catch (Exception e) {
            return ResponseUtils.handleException(e, "检查存储桶是否存在");
        }
    }

    /**
     * 设置存储桶权限
     */
    @Operation(summary = "设置存储桶权限")
    @SaCheckPermission("file:bucket:edit")
    @Log(title = "存储桶管理", businessType = BusinessType.UPDATE)
    @PutMapping("/permission")
    public AjaxResult setBucketPermission(@RequestParam("bucketName") String bucketName, @RequestParam("permission") String permission, @RequestParam(value = "configId", required = false) Long configId) {
        try {
            // 验证权限参数
            if (!java.util.Arrays.asList("private", "public-read", "public-read-write").contains(permission)) {
                return AjaxResult.error("权限参数无效，支持的权限类型：private、public-read、public-read-write");
            }

            // 获取并验证存储配置
            SysStorageConfig config = StorageConfigUtils.getAndValidateConfig(configId, storageConfigService);

            StorageService storageService = storageServiceFactory.getStorageService(config);

            // 检查桶是否存在
            if (!storageService.bucketExists(bucketName, config)) {
                return AjaxResult.error("存储桶不存在");
            }

            // 设置权限
            storageService.setBucketPermission(bucketName, permission, config);
            return AjaxResult.success("设置存储桶权限成功");
        } catch (Exception e) {
            return ResponseUtils.handleException(e, "设置存储桶权限");
        }
    }

    /**
     * 获取存储桶权限
     */
    @Operation(summary = "获取存储桶权限")
    @SaCheckPermission("file:bucket:query")
    @GetMapping("/permission")
    public AjaxResult getBucketPermission(@RequestParam("bucketName") String bucketName, @RequestParam(value = "configId", required = false) Long configId) {
        try {
            // 获取并验证存储配置
            SysStorageConfig config = StorageConfigUtils.getAndValidateConfig(configId, storageConfigService);

            StorageService storageService = storageServiceFactory.getStorageService(config);

            // 检查桶是否存在
            if (!storageService.bucketExists(bucketName, config)) {
                return AjaxResult.error("存储桶不存在");
            }

            String permission = storageService.getBucketPermission(bucketName, config);
            return AjaxResult.success(permission);
        } catch (Exception e) {
            return ResponseUtils.handleException(e, "获取存储桶权限");
        }
    }
}
